package mahjong;

import java.util.*;
import java.io.*;

/**
 * A layout of the tiles.
 * Reads in a layout file and construct a 3D array representing that layout.
 * Non-zero entry represent the presence of a tile and the value of the entry
 * gives the unique ID of that tile in the layout. Assumes 16 by 30 grid per
 * level.
 */
public class Layout
{
	/** Number of rows in a level. */
	public static final int NUMROW = 16;
	/** Number of columns in a level. */
	public static final int NUMCOL = 30;
	/** The actual layout (levels[depth][width][height]), non zero entry
	 * represents a tile present at that position with actual value of the
	 * entry being the unique ID of the tile.
	 */
	private int[][][] levels;
	/** The number of tiles used in the layout */
	private int numTiles;

	/** Layout constructor.
	 * @param filename the filename of the layout file from which the
	 * layout object is to be constructed. Assumes 16 by 30 grid per level.
	 */
	public Layout(String filename)
	{
		try {
			makeLevels(filename);
		} catch(FileNotFoundException e) {
			System.out.println("Error loading Layout");
		}
	}
	

	/** Read in the layout file and construct the layout.
	 *
	 * @param filename the filename of the layout file from which the
	 * layout object is to be constructed. Assumes 16 by 30 grid per level.
	 */
	private void makeLevels(String filename) throws FileNotFoundException
	{
		Scanner layout;
		String line;
		StringBuffer strBuf;
	       
		layout = new Scanner(new File(filename));
		strBuf = new StringBuffer();

		// Read the content
		while (layout.hasNextLine()) 
		{
			line = layout.nextLine().trim();
			if (line.length() == 0 || line.trim().charAt(0) == '%'
					|| line.trim().charAt(0) == '#') 
			{
				continue;
			}
			strBuf.append(line.replaceAll("\\D", ""));
		}

		char[] fileContent = strBuf.toString().toCharArray();
		int length = fileContent.length;

		assert(length % (NUMROW * NUMCOL) == 0);

		// Process the content
		int l = 0;
		int curTile = 1; // gives the ID of the next tile
		levels = new int[length / (NUMROW * NUMCOL)][NUMROW][NUMCOL];

		for (int z = 0; z < levels.length; z++) 
		{
			for (int y = 0; y < NUMROW; y++) 
			{
				for (int x = 0; x < NUMCOL; x++) 
				{
					// Look for the tile
					if (fileContent[l] != '0') 
					{
						// set the postion of the tile
						// with ID `curTile'
						levels[z][y][x] = curTile;
						levels[z][y][x+1] = curTile;
						levels[z][y+1][x+1] = curTile;
						levels[z][y+1][x] = curTile;
						// clear out unneeded data
						fileContent[l+1] = '0';
						fileContent[l+NUMCOL] = '0';
						fileContent[l+NUMCOL+1] = '0';
						curTile++;
					}
					l++;
				}
			}
		}

		numTiles = curTile - 1;
	}
	

	/** Get the layout as an array of levels, each level is a 16 by 30 grid.
	 * @return the layout in a 3D array.
	 */
	public int[][][] getLevels()
	{
		return levels;
	}


	/** Get the number of tiles in this layout.
	 * @return the number of tiles in this layout.
	 */
	public int getNumTiles()
	{
		return numTiles;
	}
}
